package net.tv90.bfmccore.helper;

import org.apache.commons.lang.StringUtils;
import org.bitterorange.flansmodslain.FlansModAPI;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static net.tv90.bfmccore.helper.FactionHelper.*;


public class MCHHelper {

    public static List<String> vehicleList = new ArrayList<>
            (Arrays.asList(
                    "bfmc.driver.jet", "bfmc.driver.atkjet", "bfmc.driver.aa",
                    "bfmc.driver.tank", "bfmc.driver.heli", "bfmc.driver.trans",
                    "bfmc.driver.fac" , "bfmc.driver.light"
            ));

    public static String[] checkList = {"inf", "jet", "atkjet", "aa", "tank", "trans", "heli", "fac", "light"};

    public static Map<String, Integer> vehicleLimit = new ConcurrentHashMap<>();

    public static Map<String, Integer> vehicleCooldown = new ConcurrentHashMap<>();

    static {
        flushVehicleLimit();
    }

    //获取玩家所乘坐MCH载具的类型
    //精确获取MCH载具名称
    public static String getMCHEntitiesInfo(Player p) {
        return FlansModAPI.getPlayerVehicle(p);
    }

    //获取玩家所乘坐载具的类型
    //只能获取TANK/PLANE/HELI/VEHICLE/SEAT大类
    public static String getEntitiesInfo(Player p) {
        if (p.getVehicle() != null) {
            return p.getVehicle().getType().name();
        }
        return "No Vehicle";
    }

    //获取玩家所乘坐载具的类型
    //只能获取TANK/PLANE/HELI/VEHICLE/SEAT大类
    public static String getMCHEntitiesType(Player p) {
        if (p.getVehicle() != null) {
            String s = p.getVehicle().getType().name();
            if (s.contains("TANK")) return "TANK";
            else if (s.contains("GLTD")) return "GLTD";
            else if (s.contains("PLANE")) return "PLANE";
            else if (s.contains("HELI")) return "HELI";
            else if (s.contains("VEHICLE")) return "VEHICLE";
            else if (s.contains("UAV")) return "UAV";
            else if (s.contains("SEAT")) return "TANK";
        }
        return "INF";
    }

    public static String getMCHEntitiesSoundFilterType(Player p) {
        if (p.getVehicle() != null) {
            String s = p.getVehicle().getType().name();
            if (s.contains("TANK")) return "TANK";
            else if (s.contains("PLANE")) return "JET";
            else if (s.contains("HELI")) return "HELI";
            else if (s.contains("UAV")) return "UAV";
            else if (s.contains("GLTD")) return "GLTD";
            else if (s.contains("SEAT")) return "TANK";
        }
        return "INF";
    }

    //获取玩家所乘坐载具的类型
    public static String getMCHEntitiesType_Lang(Player p) {
        if (p.getVehicle() != null) {
            String s = p.getVehicle().getType().name();
            if (s.contains("TANK")) return "地面载具驾驶员";
            else if (s.contains("GLTD")) return "SOFLAM操作员";
            else if (s.contains("PLANE")) return "飞行员";
            else if (s.contains("HELI")) return "直升机驾驶员";
            else if (s.contains("VEHICLE")) return "固定载具操作员";
            else if (s.contains("UAV")) return "无人机操作员";
            else if (s.contains("SEAT")) return "载具乘客";
        }
        return "步兵";
    }

    public static List<String> getNearbyEntitiesInfo(Player p, int radius) {
        List<String> list = new ArrayList<>();
        for (Entity entity : p.getNearbyEntities(radius, radius, radius)) {
            if (entity instanceof Player)
                continue;
            list.add(entity.getType().name() + " " + '\n');
        }
        return list;
    }

    public static Entity getClosestAircraftEntity(Player p, int radius) {
        Entity closest = null;
        double closestDistanceSq = Double.MAX_VALUE;
        Location playerLoc = p.getLocation();
        for (Entity entity : p.getNearbyEntities(radius, radius, radius)) {
            if (FlansModAPI.isMCHeliAircraft(entity)) {
                double distSq = entity.getLocation().distanceSquared(playerLoc);
                if (closest == null || distSq < closestDistanceSq) {
                    closest = entity;
                    closestDistanceSq = distSq;
                }
            }
        }
        return closest;
    }


    /**
     * 获取玩家附近最近有人乘坐的载具类型（Passenger除外）
     *
     * @param p 玩家
     * @return 载具类型
     */
    public static String getNearestMCHEntitiesInfo(Player p, int radius) {
        for (Entity entity : p.getNearbyEntities(radius, radius, radius)) {
            if (entity instanceof Player) {
                String s = getMCHEntitiesInfo((Player) entity);
                while (s.equals("PASSENGER") || s.contains("AIR") || radius < 20) {
                    radius += 5;
                    s = getNearestMCHEntitiesInfo(p, radius);
                }
                return s;
            }
        }
        return "AIR";
    }

    /**
     * @param e 载具实体
     * @return 判断载具是否处于无主状态
     */
    public static boolean isOwnerless(Entity e) {
        if (e.getType().name().startsWith("MCHELI") && !e.getType().name().contains("SEAT")) {
            for (Entity entity : e.getNearbyEntities(12, 10, 12)) {
                if (entity instanceof Player)
                    if (entity.getVehicle() != null)
                        return false;
            }
            return true;
        }
        return false;
    }

    /**
     * 清理无主状态的MCH载具
     */
    public static void clearMCHEntities() {
        int num = 0;
        for (World world : Bukkit.getWorlds()) {
            for (Entity e : world.getEntities()) {
                if (e.getType().name().startsWith("MCHELI")) {
                    //不能清理座位
                    if(e.getType().name().contains("SEAT")) continue;
                    if(e.getType().name().contains("MIS")) continue;
                    //不能清理有人驾驶的无人机
                    if(FlansModAPI.isOnlineUAV(e)){
                        continue;
                    }
                    //不能清理有人驾驶的无人机控制台 / GLTD
                    if (e.getType().name().contains("UAVSTATION") || e.getType().name().contains("GLTD")) {
                        if(e.isEmpty()){
                            e.remove();
                            num++;
                        }
                    } else if(isOwnerless(e)){
                        e.remove();
                        num++;
                    }
                }
            }
        }
        Bukkit.broadcastMessage("§e[管理员]已清理" + num + "个废弃载具");
    }

    /**
     * @param p 玩家
     * @return 获取玩家的国家和载具职业 格式 RU_JET
     */
    public static String getFactionVehicle(Player p) {
        if (p.isOp()) return "INF";
        else if (p.hasPermission("bfmc.rgf")) {
            if (p.hasPermission("bfmc.driver.jet")) {
                return "RU_JET";
            } else if (p.hasPermission("bfmc.driver.atkjet")) {
                return "RU_ATKJET";
            } else if (p.hasPermission("bfmc.driver.aa")) {
                return "RU_AA";
            } else if (p.hasPermission("bfmc.driver.tank")) {
                return "RU_TANK";
            }  else if (p.hasPermission("bfmc.driver.trans")) {
                return "RU_TRANS";
            } else if (p.hasPermission("bfmc.driver.heli")) {
                return "RU_HELI";
            }  else if (p.hasPermission("bfmc.driver.fac")) {
                return "RU_FAC";
            }  else if (p.hasPermission("bfmc.driver.light")) {
                return "RU_LIGHT";
            }
            else return "RU_INF";
        } else if (p.hasPermission("bfmc.usmc")) {
            if (p.hasPermission("bfmc.driver.jet")) {
                return "US_JET";
            } else if (p.hasPermission("bfmc.driver.atkjet")) {
                return "US_ATKJET";
            } else if (p.hasPermission("bfmc.driver.aa")) {
                return "US_AA";
            } else if (p.hasPermission("bfmc.driver.tank")) {
                return "US_TANK";
            }  else if (p.hasPermission("bfmc.driver.trans")) {
                return "US_TRANS";
            } else if (p.hasPermission("bfmc.driver.heli")) {
                return "US_HELI";
            }  else if (p.hasPermission("bfmc.driver.fac")) {
                return "US_FAC";
            } else if (p.hasPermission("bfmc.driver.light")) {
                return "US_LIGHT";
            }
            else return "US_INF";
        } else if (p.hasPermission("bfmc.pla")) {
            if (p.hasPermission("bfmc.driver.jet")) {
                return "CN_JET";
            } else if (p.hasPermission("bfmc.driver.atkjet")) {
                return "CN_ATKJET";
            } else if (p.hasPermission("bfmc.driver.aa")) {
                return "CN_AA";
            } else if (p.hasPermission("bfmc.driver.tank")) {
                return "CN_TANK";
            }  else if (p.hasPermission("bfmc.driver.trans")) {
                return "CN_TRANS";
            } else if (p.hasPermission("bfmc.driver.heli")) {
                return "CN_HELI";
            }  else if (p.hasPermission("bfmc.driver.fac")) {
                return "CN_FAC";
            } else if (p.hasPermission("bfmc.driver.light")) {
                return "CN_LIGHT";
            }
            else return "CN_INF";
        }
        return "NoFaction_INF";
    }

    /**
     * @param s 载具类别 ATKJET/JET/TANK等 大小写均可
     * @return 载具中文翻译
     */
    public static String getVehicle_Lang(String s) {
        switch (s.toUpperCase()) {
            case "LIGHT":
                return "支援载具";
            case "ATKJET":
                return "攻击机";
            case "JET":
                return "战斗机";
            case "TANK":
                return "地面载具";
            case "AA":
                return "防空车";
            case "HELI":
                return "攻击直升机";
            case "TRANS":
                return "支援直升机";
            case "FAC":
                return "攻击快艇";
        }
        return "";
    }

    /**
     * @param s 载具类别 US_ATKJET
     * @return 载具中文翻译
     */
    public static String getVehicle_Lang_2(String s) {
        if (s.endsWith("_JET")) return "战斗机";
        else if (s.endsWith("_LIGHT")) return "支援载具";
        else if (s.endsWith("_ATKJET")) return "攻击机";
        else if (s.endsWith("_AA")) return "防空车";
        else if (s.endsWith("_TANK")) return "地面载具";
        else if (s.endsWith("_TRANS")) return "支援直升机";
        else if (s.endsWith("_HELI")) return "攻击直升机";
        else if (s.endsWith("_FAC")) return "攻击快艇";
        return "";
    }

    /**
     * 将玩家设置为步兵
     *
     * @param p 玩家
     */
    public static void setINF(Player p) {
        for (String s : vehicleList) {
            if (p.hasPermission(s)) {
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + p.getName() + " permission unset " + s);
                String s1 = s.split("\\.")[2];
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "lp user " + p.getName() + " permission unset " + "bfmc.driver." + s1.toUpperCase());
            }
        }
    }

    /**
     * 获取不同种类载具的限制数量
     *
     * @param s 载具类别 ATKJET/JET/TANK等 大小写均可
     * @return 限制数量
     */
    public static int getVehicleLimit(String s) {
        return vehicleLimit.get(s.toUpperCase());
    }

    /**
     * 刷新载具限制
     */
    public static void flushVehicleLimit() {
        vehicleLimit.clear();
        vehicleLimit.put("LIGHT", 1);
        vehicleLimit.put("ATKJET", 1);
        vehicleLimit.put("JET", 1);
        vehicleLimit.put("TANK", 2);
        vehicleLimit.put("AA", 1);
        vehicleLimit.put("HELI", 1);
        vehicleLimit.put("TRANS", 1);
        vehicleLimit.put("FAC", 1);
    }

    /**
     * 刷新不同种类载具的冷却时间
     */
    public static void flushVehicleCooldown() {
        vehicleCooldown.clear();
        vehicleCooldown.put("LIGHT", 60);
        vehicleCooldown.put("ATKJET", 220);
        vehicleCooldown.put("JET", 160);
        vehicleCooldown.put("TANK", 80);
        vehicleCooldown.put("AA", 180);
        vehicleCooldown.put("HELI", 220);
        vehicleCooldown.put("TRANS", 120);
        vehicleCooldown.put("FAC", 120);
    }

    /**
     * 获取购买不同种类载具的冷却时间
     *
     * @param s 载具类别
     * @return 冷却时间
     */
    public static int getVehicleCooldownTime(String s) {
        if (s.endsWith("_JET")) return vehicleCooldown.get("JET");
        else if (s.endsWith("_LIGHT")) return vehicleCooldown.get("LIGHT");
        else if (s.endsWith("_ATKJET")) return vehicleCooldown.get("ATKJET");
        else if (s.endsWith("_AA")) return vehicleCooldown.get("AA");
        else if (s.endsWith("_TANK")) return vehicleCooldown.get("TANK");
        else if (s.endsWith("_TRANS")) return vehicleCooldown.get("TRANS");
        else if (s.endsWith("_HELI")) return vehicleCooldown.get("HELI");
        else if (s.endsWith("_FAC")) return vehicleCooldown.get("FAC");
        return 0;
    }


    public static int getDistance(Location player, Location entity) {
        Vector vector = player.subtract(entity).toVector();
        return (int) Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getY(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
    }

    public static void selectVehicle(String mapName, Player player, String vehicle, String point) {
        String hasPoint = StringUtils.isEmpty(point) ? "" : "_" + point;
        if (vehicle.equals("inf")) {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "cc open " +
                    mapName + "_" + getFactionVehicle(player) + hasPoint + " " + player.getName());
        } else {
            String faction_vehicle = getCountry2(player) + "_" + vehicle.toUpperCase();
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "cc open " +
                    mapName + "_" + faction_vehicle + hasPoint + " " + player.getName());
        }
    }

}
